﻿using SPSDeploy.Extensions.Controllers;
using System;
using System.Text;
using System.Xml.Linq;

namespace SPSDeploy.Extensions.Modules.Compare
{
    /// <summary>
    /// Base compare module
    /// </summary>
    internal abstract class BaseModule : SPSDeploy.Extensions.Modules.BaseModule
    {

        /// <summary>
        /// Initialization
        /// </summary>
        /// <param name="controller"></param>
        internal BaseModule(BaseController controller)
            : base(controller)
        {
        }

        /// <summary>
        /// Execute module
        /// </summary>
        /// <param name="compare"></param>
        /// <param name="parent"></param>
        /// <returns></returns>
        internal abstract XElement Execute(XElement compare, XElement parent);

        /// <summary>
        /// Return adds element
        /// </summary>
        /// <returns></returns>
        protected XElement GetAddsElement()
        {
            return new XElement("adds");
        }

        /// <summary>
        /// Return updates element
        /// </summary>
        /// <returns></returns>
        protected XElement GetUpdatesElement()
        {
            return new XElement("updates");
        }

        /// <summary>
        /// Return update element
        /// </summary>
        /// <param name="name"></param>
        /// <param name="fromValue"></param>
        /// <param name="toValue"></param>
        /// <returns></returns>
        protected XElement GetUpdateElement(XName name, string fromValue, string toValue)
        {
            return new XElement("update", new XAttribute("value", name), new XAttribute("from", fromValue), new XAttribute("to", toValue));
        }

        /// <summary>
        /// Return deletes element
        /// </summary>
        /// <returns></returns>
        protected XElement GetDeletesElement()
        {
            return new XElement("deletes");
        }

        /// <summary>
        /// Compare attribute value
        /// </summary>
        /// <param name="updates"></param>
        /// <param name="attribute"></param>
        /// <param name="value"></param>
        protected void Compare(XElement updates, XAttribute attribute, string value)
        {
            if (attribute.Value != value)
                updates.Add(GetUpdateElement(attribute.Name, value, attribute.Value));
        }

        /// <summary>
        /// Compare attribute value
        /// </summary>
        /// <param name="updates"></param>
        /// <param name="attribute"></param>
        /// <param name="value"></param>
        protected void Compare(XElement updates, XAttribute attribute, int value)
        {
            if (attribute.Value != value.ToString())
                updates.Add(GetUpdateElement(attribute.Name, value.ToString(), attribute.Value));
        }

        /// <summary>
        /// Compare attribute value
        /// </summary>
        /// <param name="updates"></param>
        /// <param name="attribute"></param>
        /// <param name="value"></param>
        protected void Compare(XElement updates, XAttribute attribute, bool value)
        {
            if (Boolean.Parse(attribute.Value) != value)
                updates.Add(GetUpdateElement(attribute.Name, value.ToString(), attribute.Value));
        }

        /// <summary>
        /// Add update element
        /// </summary>
        /// <param name="updates"></param>
        /// <param name="element"></param>
        /// <param name="text"></param>
        /// <param name="elementText"></param>
        protected void AddUpdateElement(XElement updates, XElement element, StringBuilder text, StringBuilder elementText)
        {
            AddUpdateElement(updates, element, text.ToString(), elementText.ToString());
        }

        /// <summary>
        /// Add update element
        /// </summary>
        /// <param name="updates"></param>
        /// <param name="element"></param>
        /// <param name="text"></param>
        /// <param name="elementText"></param>
        protected void AddUpdateElement(XElement updates, XElement element, string text, string elementText)
        {
            if (text != elementText)
            {
                XElement update = GetUpdateElement(element.Name, text, elementText);
                update.Add(element);
                updates.Add(update);
            }
        }

    }
}